var zookeeper = require("node-zookeeper-client");
var configZookeeper = require('../../config/zookeeper');

(function(){

    var ZkService = {};

    ZkService.createApplicationMonitor = function (done) {

        var zkclientAppMon;
        var zkclientAppMonIP = configZookeeper.zkclientIP;
        var applicationPath = configZookeeper.applicationPath;

        function creatClient(next) {
            console.log("ZkService:creatClient");
            zkclientAppMon = zookeeper.createClient(zkclientAppMonIP);
            zkclientAppMon.connect();

            zkclientAppMon.on("error", function (error) {
                return next(err);
            });

            zkclientAppMon.on("connected", function (error) {
                return next();
            });

            setTimeout(function(){
                if(zkclientAppMon.getState() !=zookeeper.State.SYNC_CONNECTED){
                    next({"status":500,"result":"ZkService zookeeper can not connect"});
                }
            },20000);

        }

        function existsNode(next) {
            var path = applicationPath;
            zkclientAppMon.exists(
                path,
                function (error, stat) {
                    if (error) {
                        console.log(
                            'ZkService Failed to check existence of node: %s due to: %s.',
                            path,
                            error
                        );
                        next(error);
                    }

                    if (stat) {
                        console.log(
                            'ZkService Node: %s exists and its version is: %j',
                            path,
                            stat.version
                        );
                        next(null, true);
                    } else {
                        console.log('ZkService Node %s does not exist.', path);
                        next(null, false);
                    }
                }
            );
        }

        function deleteNode(isExist,next) {
            var path = applicationPath;
            if(isExist) {
                zkclientAppMon.remove(path, function (error) {
                    if (error) {
                        console.log(
                            'Failed to delete node: %s due to: %s.',
                            path,
                            error
                        );
                        return next(error);
                    }

                    console.log('Node: %s is deleted.', path);
                    next();
                });
            } else {
                next();
            }
        }

        function createNode(next) {
            var path = applicationPath;
            zkclientAppMon.create(path, zookeeper.CreateMode.EPHEMERAL, function (error) {
                if (error) {
                    console.log('ZkService Failed to create node: %s due to: %s.', path, error);
                    next(error);
                } else {
                    console.log('ZkService Node: %s is successfully created.', path);
                    next();
                }
            });
        }

        function setData(next) {

            var path = applicationPath;

            setInterval(function() {
                var configData = configZookeeper.reportData;

                var configDataString = JSON.stringify(configData);
                zkclientAppMon.setData(path, new Buffer(configDataString), function (error, stat) {
                    if (error) {
                        console.log("ZkService setData ERROR:", error);
                        zkclientAppMon.close();
                        return next(error);
                    }
                });
            }, configZookeeper.applicationTimeout);

            return next(null);

        }

        async.waterfall([
            creatClient,
            existsNode,
            deleteNode,
            createNode,
            setData
        ], function (error, result) {

        });

        return done();

    }

    module.exports = ZkService;
})();
